<?php
/**
 * 请求类
 */
namespace core;
class Request{
	private static $instance;
	private static $params = array();
	public static function init() {
		if(!self::$instance){
			self::$instance = new Request();
		}

		return self::$instance;
	}

	// 获取参数
	public function getParams($name = '', $method = 'get') {
		if(empty($name)) {
			// 自动判断是get还是post
			if($this->method() === 'GET') {
				$params = empty($_GET) ? self::$params : $_GET;
			}elseif($this->method() === 'POST'){
				$params = $_POST;
			}
		}else{
			if($method === 'get') {
				$params = $this->get($name);
			}elseif ($method === 'post') {
				$params = $this->post($name);
			}else{
				$params = false;
			}
		}

		if(!$params) {
			throw new \Exception("当前请求未包含此参数:" . $name);
			
		}

		return $params;
	}

	// 获得get参数
	public function get($name) {
		return isset(self::$params[$name]) ? self::$params[$name] : (isset($_GET[$name]) ? $_GET[$name] : false);
	}

	// 获得post参数
	public function post($name) {
		return isset($_POST[$name]) ? $_POST[$name] : false;
	}

	// 自动获取请求方法
	private function method(){
		return $_SERVER['REQUEST_METHOD'];
	}

	// 得到pathinfo
	public function path() {

		return empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');
	}

	// 解析控制器和方法
	public function parseUrl($url){
		$url = strtolower($url);
		// 启用默认的控制器和action
		$name = '';
		if($url === '/') {
			$name = DEFUALT_CONTROLLER  . '/' . DEFUALT_ACTION;			
		}else{

			if(ROUTE_ON) {
				if(!is_file(CONFIG . 'route.php')){
					throw new \Exception('路由文件不存在');	
				}
				$params = self::parseRouteUrl($url);
				if($params){

					$url = self::formatPathinfo($params['path'], $params['var']);
				}
				
			}

			$path = self::parseUrlPath($url);

			if(is_array($path)) {
				$controller = array_shift($path);
				$action = array_shift($path);
			}
			
			$name =  $controller . '/'  . $action;

			// 解析参数
			self::parseUrlParams(!empty($path) ? implode('/', $path) : '');
		}

		return [$name, self::$params];

	}

	// 反向拼接path info
	private static function formatPathinfo($path, $params) {
		$path = rtrim($path, '/');
		$pathinfo = $path;
		foreach ($params as $key => $value) {
			$pathinfo .= '/' . $key . '/' . $value;
		}

		return rtrim($pathinfo, '/');
	}

	// 解析路由URL
	private static function parseRouteUrl($url){
		if(!is_file(CONFIG . 'route.php')){
			throw new Exception('路由文件不存在');	
		}
		$routes = include_once CONFIG . 'route.php';
		if(empty($routes)) {
			return false;
		}

		$params = explode('/', $url);
		foreach ($routes as $key => $value) {
			
			if(false !== $matchs = self::match($key, $params)){
				$matchs['path'] = $value;
				return $matchs;
			}
		}

		return false;
		
	}

	// 匹配路由规则
	private static function match($rule, $params) {

		$rules = explode('/', $rule);
		$var = [];
		// 查找变量
		foreach ($rules as $k => $rule) {
			if(false !== strpos($rule, ':')) {
				$var[substr($rule, 1)] = isset($params[$k]) ? $params[$k] : '';
			}elseif(!isset($params[$k]) || 0 !== strcasecmp($params[$k], $rule)){
				return false;
			}
		}
		return ['var' => $var];
	}

	// 解析pathinfo
	public static function parseUrlPath($url) {
		$path = explode('/', $url);
		return $path;
	}

	// 解析pathinfo参数
	public static function parseUrlParams($url){
		if(!$url) {
			return false;
		}

		$params = explode('/', $url);
		// 成对解析参数
		$t = $params;
		foreach ($params as $key => $value) {
			// 如果最后一参数少了值那么就不去写入参数

			if(isset($params[$key + 1])){
				if(!$t) {
					break;
				}
				self::$params[array_shift($t)] = array_shift($t);
			}

		}
	}
}